package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

func initReq(ip string) *http.Request {
	req, _ := http.NewRequest("GET", "http://"+ip+"/EXCU_SHELL", nil)
	req.AddCookie(&http.Cookie{
		Name:  "auth",
		Value: "YWRtaW46YWRtaW4%3D",
	})
	req.AddCookie(&http.Cookie{
		Name:  "userManage",
		Value: "YWRtaW4%3D",
	})
	req.AddCookie(&http.Cookie{
		Name:  "passManage",
		Value: "YWRtaW4%3D",
	})
	req.AddCookie(&http.Cookie{
		Name:  "pass",
		Value: "loginsuccess",
	})
	req.AddCookie(&http.Cookie{
		Name:  "mainIPAddress",
		Value: "",
	})
	req.AddCookie(&http.Cookie{
		Name:  "currentURL",
		Value: "1",
	})

	return req

}

//GetPOEChannelInfo 获取POE参数
func getPOEChannelInfo(ip string) map[string]interface{} {
	channelInfo := sendCmd(ip, "", "show%20%20poe%20%20interfaces%20GigabitEthernet%200/1-0/10", "show%20poe%20powersupply",
		"EN")
	if channelInfo != nil {
		states := getPOEState(ip)
		var activeMap map[string]string
		if states != nil {
			for k, v := range states {
				info := channelInfo[k]
				if info != nil {
					mapInfo, _ := info.(map[string]string)
					activeMap = mapInfo
					if mapInfo != nil {
						mapInfo["Connect Status"] = v["Status"]
						mapInfo["Type"] = v["Type"]
						mapInfo["Speed"] = v["Speed"]
					}
				}
			}
			for ik, iv := range states {
				_, ok := channelInfo[ik]
				if !ok {
					mapInfo := make(map[string]string)
					//ivmap, ok := iv.(map[string]string)

					channelInfo[ik] = mapInfo
					mapInfo["Type"] = iv["Type"]
					mapInfo["Speed"] = iv["Speed"]
					mapInfo["Connect Status"] = iv["Status"]
					mapInfo["Interface"] = ik
					for title := range activeMap {
						_, ok := mapInfo[title]
						if !ok {
							mapInfo[title] = "-"
						}

					}
				}
			}
		}

	}
	return channelInfo

}

func getPOEState(ip string) (res map[string](map[string]string)) {
	req := initReq(ip)
	/*
			command1: show%20interfaces%20status
		command2: show%20link-aggregation%20group
		command3: show%20running-config%20interfaces%20GigabitEthernet%200/1-0/10
		command4: show%20running-config%20interfaces%20Aggregateport%201-8
		confirm1: n
		confirm2: n
		confirm3: n
		confirm4: n
	*/
	req.Header.Add("mode", "EN")
	//req.Header.Add("command4", "show%20running-config%20interfaces%20Aggregateport%201-8")
	//req.Header.Add("command3", "show%20running-config%20interfaces%20GigabitEthernet%200/1-0/10")
	//req.Header.Add("command2", "show%20link-aggregation%20group")
	req.Header.Add("command1", "show%20interfaces%20status")
	req.Header.Add("cmdnum", "1")
	req.Header.Add("confirm1", "n")
	client := &http.Client{}
	resp, _ := client.Do(req)
	if resp == nil {
		return nil
	}
	body, _ := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	//info := string(body)
	end := bytes.Index(body, []byte("@@@@@@"))
	pro := body[0:end]
	//begin := 0
	titles := make([]string, 0, 4)
	for {
		end = bytes.Index(pro, []byte("\n"))
		if end < 0 {
			break
		}
		line := string(pro[0:end])
		pro = pro[end+1:]
		if len(line) > 10 {
			parts := strings.Split(line, "|")
			if len(parts) >= 7 {
				parts[0] = strings.TrimSpace(parts[0])
				if parts[0] == "Interface" {
					res = make(map[string]map[string]string)
					for _, item := range parts {
						item = strings.TrimSpace(item)
						titles = append(titles, item)

					}

					continue
				}
				items := make(map[string]string)
				res[parts[0]] = items
				for i, item := range parts {
					item = strings.TrimSpace(item)
					if i < len(titles) {
						items[titles[i]] = item
					}

				}
			}
		}

	}
	return res
}

func enablePOE(ip string, no string, isEanble bool) {
	req := initReq(ip)
	req.Header.Add("confirm2", "n")
	req.Header.Add("confirm1", "n")
	req.Header.Add("confirm3", "n")
	req.Header.Add("cmdnum", "3")
	if !isEanble {
		req.Header.Add("command3", "no%20poe%20enable")
	} else {
		req.Header.Add("command3", "poe%20enable")
	}

	req.Header.Add("mode", "CONF")

	req.Header.Add("command2", "poe%20%20max-powe%2035")

	//command1: interface%20%20range%20GigabitEthernet%200/5,0/6,0/1

	req.Header.Add("command1", "interface%20%20range%20GigabitEthernet%20"+no)

	client := &http.Client{}
	resp, _ := client.Do(req)
	if resp != nil && resp.Body != nil {
		resp.Body.Close()
	}
	//defer
}

func sendCmd(ip string, cmd1, cmd2, cmd3, mod string) map[string]interface{} {
	req := initReq(ip)
	req.Header.Add("confirm2", "n")
	req.Header.Add("confirm1", "n")
	req.Header.Add("confirm3", "n")
	req.Header.Add("cmdnum", "3")
	req.Header.Add("mode", mod)
	req.Header.Add("command3", cmd3)
	req.Header.Add("command2", cmd2)
	if cmd1 != "" {
		req.Header.Add("command1", cmd1)
	}

	client := &http.Client{}
	resp, _ := client.Do(req)
	if resp == nil {
		return nil
	}
	body, _ := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	//info := string(body)
	begin := bytes.Index(body, []byte("@@@@@@"))
	current := body[begin+6:]
	result := make(map[string]interface{})
	var currentMap map[string]string
	result["poe_addr"] = ip
	end := 0
	for end >= 0 {

		end = bytes.Index(current, []byte("\n"))
		var line string
		if end == -1 {
			line = string(current[0:])
		} else if end == 0 {
			current = current[1:]
			continue
		} else {
			line = string(current[0:end])
			//begin = end + 1
		}

		parts := strings.Split(line, " : ")
		fmt.Println("line------------------", end, line, parts)
		if len(parts) == 2 {
			parts[0] = strings.TrimSpace(parts[0])
			parts[1] = strings.TrimSpace(parts[1])
			if parts[0] == "Interface" {
				currentMap = make(map[string]string)
				result[parts[1]] = currentMap
			}
			if currentMap != nil {
				currentMap[parts[0]] = parts[1]
			}

		}
		current = current[end+1:]

	}
	return result
}
